/*
 * $Id: OnwatchTask.java,v 1.7 2009/08/14 05:51:17 afaichun Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.processor.dispatcher.tasks;

import org.springframework.util.Assert;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.database.dao.ICodeDetailsDAO;
import com.ge.healthcare.autosc.common.database.dao.IOnwatchTaskDAO;
import com.ge.healthcare.autosc.common.database.dao.IRequestDAO;
import com.ge.healthcare.autosc.common.database.dao.IRequestTypeDAO;
import com.ge.healthcare.autosc.common.database.pojo.ActOnwatchTask;
import com.ge.healthcare.autosc.common.database.pojo.ActRequest;
import com.ge.healthcare.autosc.common.database.pojo.ActTask;
import com.ge.healthcare.autosc.common.database.pojo.CfgRequestType;
import com.ge.healthcare.autosc.common.dbLogger.StepLogger;
import com.ge.healthcare.autosc.common.exceptions.BasicException;
import com.ge.healthcare.autosc.common.prodiags.ProdiagsScheduleTask;
import com.ge.healthcare.autosc.common.prodiags.ProdiagsTaskParamsMap;
import com.ge.healthcare.autosc.common.util.ApplicationInfo;
import com.ge.healthcare.autosc.common.util.PropertyConstants;
import com.ge.healthcare.autosc.common.util.TimeFormatStandard;
import com.ge.healthcare.autosc.processor.PrcCodeConstants;
import com.ge.healthcare.autosc.processor.exception.TaskException;

public class OnwatchTask extends BasicTask {

	protected ActTask task = null;
	private static IOnwatchTaskDAO onwatchTaskDAO = null;
	private static ICodeDetailsDAO codeDetailsDAO = null;
	private static IRequestDAO requestDAO = null;
	private static IRequestTypeDAO requestTypeDAO = null;
	
	public void init() {
		Assert.notNull(onwatchTaskDAO,
				"ActOnwatchTaskDAO object is required. Use setActOnwatchTaskDAO() to provide one.");
		Assert.notNull(codeDetailsDAO,
			"CodeDetailsDAO object is required. Use setCodeDetailsDAO() to provide one.");
		Assert.notNull(requestDAO,
			"requestDAO object is required. Use setActRequestDAO() to provide one.");
		Assert.notNull(requestTypeDAO,
			"requestTypeDAO object is required. Use setActRequestTypeDAO() to provide one.");
	}
	
	@Override
	public void executeTask(ActTask actTask) {
		String methodName = "executeTask";
		ASCLogger.debug(this.getClass(), methodName,
				"Starting OnWatchTask for task:" + task);
		this.task = actTask;
		validateProdiagsSchedule();
		createOnWatchTask();
		updateActTaskCode();
	}

	public void setActOnwatchTaskDAO(IOnwatchTaskDAO onwatchTaskDAO) {
		OnwatchTask.onwatchTaskDAO = onwatchTaskDAO;
	}
	
	public void setCodeDetailsDAO(ICodeDetailsDAO codeDetailsDAO) {
		OnwatchTask.codeDetailsDAO = codeDetailsDAO;
	}
	
	public void setActRequestDAO(IRequestDAO requestDAO) {
		OnwatchTask.requestDAO = requestDAO;
	}
	
	public void setActRequestTypeDAO(IRequestTypeDAO requestTypeDAO) {
		OnwatchTask.requestTypeDAO = requestTypeDAO;
	}
	
	private void validateProdiagsSchedule() {
		ActRequest request = requestDAO.getRequest(task);
		if(request != null) {
			CfgRequestType requestType = 
					(CfgRequestType)requestTypeDAO.getRequestTypeByRequestListId(request.getRequestListId());
			if(requestType.matchRequestType(
					ApplicationInfo.getInstance().getProperty(PropertyConstants.PRODIAGS_SCHEDULE_REQUEST_TYPE_NAME))) {
				validateProdiagsTaskParams(request);
			}
		} else {
			throw new TaskException("Cannot find request from task " + task, PrcCodeConstants.PRC_F_PRD_002);
		}
	}
	
	private void validateProdiagsTaskParams(ActRequest request) {
		try {
			ProdiagsTaskParamsMap taskParamMap = new ProdiagsTaskParamsMap(request);
			Integer[] taskKey = taskParamMap.getProdiagsTaskIndexes();
			for(int idx=0;idx < taskKey.length;idx++) {
				ProdiagsScheduleTask scheduleTask = taskParamMap.getProdiagsTask(taskKey[idx]);
				if(!scheduleTask.isTaskValid()) {
					throw new TaskException("Prodiags schedule task does not fulfill required parameter requirement. Prodiags task: " + 
							scheduleTask, PrcCodeConstants.PRC_F_PRD_001);
				}
			}
		} catch (BasicException be) {
			throw new TaskException("Unable to validate parameters of given prodiags task", PrcCodeConstants.PRC_F_PRD_002);
		}
	}
	
	private void createOnWatchTask() {
		ActOnwatchTask onwatchTask = new ActOnwatchTask();
		onwatchTask.setEnteredDate(TimeFormatStandard.getNowMillis());
		onwatchTask.setStatus(ActOnwatchTask.NEW_STATUS);
		onwatchTask.setTaskId(task.getTaskId());
		onwatchTask.setTaskOrder(new Long(0));
		onwatchTask.setExecutionTimeInSec(new Long(0));
		onwatchTaskDAO.save(onwatchTask);
		StepLogger.addStepLog("Successfully created onwatchTask " + 
				onwatchTask.getOnwatchTaskId() + " for ActTask " + task.getTaskId());
	}
	
	private void updateActTaskCode() {
		ActTask actTask = iTaskDAO.getTaskByID(task.getTaskId());
		actTask.setTaskCode(codeDetailsDAO, PrcCodeConstants.PRC_P_APP_001);
		iTaskDAO.save(actTask);
	}
}
